《数据结构与算法分析-C语言描述》C++实现(CPP 重构版本)

data structures and algorithm analysis in C

《数据结构与算法分析——C语言描述》

1、运行环境

  • Windows
  • VS 2017
  • cpp

2、参考资料

3、代码说明

CPP复现代码。

注意,由于时间关系

  • 图论Graph算法,未复现。沿用Master分支的C/C++混合代码
  • 未实现测试样例test.cpp代码

以下为代码说明

  • List:链表
struct SingleListNode
{
    int val;
    SingleListNode* next;
    SingleListNode(int val) : val(val), next(nullptr) {};
    SingleListNode() : val(0), next(nullptr) {};
};

class SingleList
{
private:
    SingleListNode * head = nullptr;
public:
    SingleList(int val);
    SingleList();
    ~SingleList();

    //1 初始化链表,O(N)
    void produceList(const int A[], int size);
    //2 获取链表长度,O(N)
    int size();
    //3 查找,O(N)
    bool find(int x);
    //4 删除(index,从0开始),O(N)
    void delete_withIndex(int index);
    //5 插入(index,从0开始),O(N)
    void insert_x_beforeIndex(int x, int index);
    //6 清空链表,O(N)
    void clear();
    //7 打印链表,O(N)
    void print();
};
  • Queue:队列
class Queue
{
public:
    Queue();
    Queue(int val);
    ~Queue();

    //1 判断是否空,O(1)
    bool empty();
    //2 获取队列size,O(1)
    int size();
    //3 尾部入队,O(1)
    void enqueue(int x);
    //4 头部出队,O(1)
    int dequeue();
    //5 清空,O(N)
    void clear();
    //6 打印,O(N)
    void print();

private:
    // 头尾指针同时维护
    QueueNode * queueFront;
    QueueNode* queueBack;
};
  • Stack:栈
class Stack
{
public:
    Stack();
    Stack(int val);
    ~Stack();

    //1- 获取size,O(1)
    int size();
    //2- 判断空,O(1)
    bool empty();
    //3- push,O(1)
    void push(int x);
    //4- pop,O(N)
    void pop();
    //5- top,O(N)
    int top();
    //6- 清空,O(N)
    void clear();
    //7- 打印,O(N)
    void print();

private:
    StackNode * stackBottom;
    StackNode * stackTop;
};
  • Tree:树
struct TreeNodeBinary{
    int val;
    TreeNodeBinary *left;
    TreeNodeBinary *right;
    TreeNodeBinary(): val(0), left(nullptr), right(nullptr) {};
    TreeNodeBinary(int val): val(0), left(nullptr), right(nullptr) {};
};
enum TraversalFlag {
    PRE_ORDER=1,
    MID_ORDER,
    AFTER_ORDER,
    LEVEL_ORDER
};

//1 普通二叉树
class BinaryTree
{
public:
    BinaryTree();
    BinaryTree(int val);
    ~BinaryTree();

    //N为节点总数
    //1 获取树的高度,O(N)
    int height();
    //2 前序/中序/后序/层序遍历,O(N)
    std::vector<int> Traversal(enum TraversalFlag flag);
    //3 DFS应用1:树的查找,O(N)
    TreeNodeBinary* find(int val);
    //4 DFS应用2:打印所有【根 => 叶节点】路径,O(N)
    std::vector<std::string> getPath();
    //5 DFS应用3:树清空,O(N)
    void clear();

private:
    TreeNodeBinary* root;
    std::vector<int> traversalVals;
    std::vector<std::string> paths;
    std::vector<std::vector<int>> levelVals;

    //1 获取树的高度
    int _height(TreeNodeBinary* r);
    //2 前序/中序/后序/层序遍历
    void _preOrder(TreeNodeBinary* r);
    void _midOrder(TreeNodeBinary* r);
    void _afterOrder(TreeNodeBinary* r);
    void _levelOrder(TreeNodeBinary* r);
    void _Traversal(TreeNodeBinary* r, enum TraversalFlag flag);
    //3 DFS应用1:树的查找
    void _find(TreeNodeBinary* r, int val, TreeNodeBinary* &ans);
    //4 DFS应用2:打印所有【根 => 叶节点】路径
    void _getPath(TreeNodeBinary * r, std::string cur);
    //5 DFS应用3:树清空
    void _clear(TreeNodeBinary* r);
};

//2 二叉查找树(左小右大)
class BinarySearchTree:public BinaryTree
{
public:
    BinarySearchTree();
    BinarySearchTree(std::vector<int> vals);
    ~BinarySearchTree();

    //1 插入,O(logN)
    void insert(int val);
    //2 查找,O(logN)
    bool find(int val);
    int findMax();
    int findMin();
    //3 删除,O(logN)
    void erase(int val);
private:
    TreeNodeBinary * root;

    //1 插入
    TreeNodeBinary* _insert(int val, TreeNodeBinary* r);
    //2 查找
    TreeNodeBinary* _find(int val, TreeNodeBinary* r);
    TreeNodeBinary* _findMax(TreeNodeBinary* r);
    TreeNodeBinary* _findMin(TreeNodeBinary* r);
    //3 删除
    TreeNodeBinary* _erase(int val, TreeNodeBinary* r);
};
  • Heap:堆
//1 二叉堆
enum HEAP_TYPE {
    MAX=INT_MAX,
    MIN=INT_MIN
};

struct HeapBinary
{
    // heapArray数组长度/容量为(capacity + 1),包括堆顶heapArray[0]
    int capacity;
    // size代表目前堆中已有元素个数
    int size;
    // heapArray[0]默认为INT_MIN(最小堆),可以设置输入参数flag设置最小/最大
    int *heapArray;

    //
    HeapBinary(enum HEAP_TYPE flag = MIN) :capacity(1), size(0) {
        heapArray = new int[1];
        heapArray[0] = flag;
    }
    HeapBinary(int capacity, enum HEAP_TYPE flag = MIN) :capacity(capacity), size(0) {
        heapArray = new int[1];
        heapArray[0] = flag;
    }
    HeapBinary(int capacity, int size, enum HEAP_TYPE flag = MIN) :capacity(capacity), size(size) {
        heapArray = new int[1];
        heapArray[0] = flag;
    }
};

class Heap
{
public:
    Heap();
    Heap(std::vector<int> vals, enum HEAP_TYPE flag=MIN);
    ~Heap();

    //1 入队,即插入1个值,O(logN)
    void enqueue(int val);
    //2 出队,即删除堆顶,并重新调整堆,O(logN)
    int dequeue();
    //3 获取,O(1)
    int getSize();
    int getHeapTop();
    //4 清空,O(1)
    void clear();
    //5 二叉堆应用1:堆排序/获取TopK的值,O(NlogN)
    std::vector<int> heapSort();

private:
    HeapBinary * heap;
};

//2 左式堆,只实现最小堆版本
struct TreeNodeHeapLeft
{
    int val;
    TreeNodeHeapLeft* left;
    TreeNodeHeapLeft* right;
    //左式堆树节点特有属性Npl
    //    Npl是 null path length 的缩写,
    //    指的是从该结点到达一个没有两个孩子的结点的最短距离(一个孩子的结点或者叶子)。
    //    一般定义NULL的Npl为-1以使计算简便
    int Npl;

    TreeNodeHeapLeft() :val(0), left(nullptr), right(nullptr), Npl(-1) {};
    TreeNodeHeapLeft(int val) :val(val), left(nullptr), right(nullptr), Npl(0) {};
};

class HeapLeft
{
public:
    HeapLeft();
    HeapLeft(std::vector<int> vals);
    ~HeapLeft();

    //1 merge合并,O(logN)
    TreeNodeHeapLeft* merge(TreeNodeHeapLeft* h1, TreeNodeHeapLeft* h2);
    //2 入队,即插入1个值,O(logN)
    void enqueue(int val);
    //3 出队,即删除堆顶,并重新调整堆,O(logN)
    int dequeue();
    //3 获取,O(1)
    int getHeapTop();
private:
    TreeNodeHeapLeft * root;
};
  • HashMap:哈希表
//1 方法1
// 解决冲突方法1 基于链表
//    分离链接法(separate chainning method):将hashval相同的,保存在1个链表数组中
class HashMap1
{
public:
    HashMap1();
    HashMap1(int size);
    // 建表,O(N*M)
    HashMap1(int size, const int keys[], int N);
    ~HashMap1();

    // N为链表个数,M为哈希表大小size
    //1 下一个质数,用来更新size,O(N^1.5)
    int nextPrime(int N);
    //2 自定义哈希函数,O(1)
    int hashFuntion(int key);
    //3 哈希表查找,O(N)(最坏)
    int find(int key);
    //4 哈希表插入,O(N)(最坏)
    void insert(int key);
    //5 哈希表删除,O(N)(最坏)
    void erase(int key);
    //6 获取哈希表size,O(1)
    int size();
    //7 哈希表清空,O(N)
    void clear();
private:
    std::vector<std::vector<HashNode1>> hashMap1;
};


//1 方法2
// 解决冲突方法2
//    开放定址法
enum kindOfEntry{
    EMPTY = 0,
    FILLED
};
struct HashNode2{
    int val;
    enum kindOfEntry info;
    HashNode2(int val) : val(val), info(EMPTY) {};
    HashNode2() : val(0), info(EMPTY) {};
};
enum detectFlag {
    LINE_DETECT = 1,
    TWICE_DETECT,
    //REHASS_DETECT
};


class HashMap2
{
public:
    HashMap2();
    HashMap2(int mapSize);
    // 建表,O(N)
    HashMap2(int mapSize, const int keys[], int N, enum detectFlag flag=LINE_DETECT);
    ~HashMap2();

    //N为哈希表大小
    //1 下一个质数,用来更新size,O(N^1.5)
    int nextPrime(int N);
    //2 自定义哈希函数,O(1)
    int hashFuntion(int key);
    //3 哈希表查找,O(1)/O(N)(线性/二次)
    int detect(int key, int currentPos, int collisionNum, enum detectFlag flag = LINE_DETECT);
    int find(int key, enum detectFlag flag = LINE_DETECT);
    //4 哈希表插入,O(1)/O(N)(线性/二次)
    void insert(int key, enum detectFlag flag = LINE_DETECT);
    //5 哈希表删除,O(1)/O(N)(线性/二次)
    void erase(int key, enum detectFlag flag = LINE_DETECT);
    //6 哈希表清空,O(N)
    void clear();
private:
    int size;
    std::vector<HashNode2> hashMap2;
};
  • UnionFindSet:并查集
class UnionFindSet
{
public:
    UnionFindSet(int NUMSETS = 8);
    ~UnionFindSet();
    void union1(int root1, int root2);
    void union2(int root1, int root2);
    void union3(int root1, int root2);
    int find(int value);
private:
    std::vector<int> unionFindSet;
};
  • Graph:图(未复现,直接用C/C++混合版本)
//general functions
struct listNode;
typedef struct listNode *ptrToNode;    //the List[i] pointer(i>0)
typedef ptrToNode List;    //the List[0] pointer

struct adjList_DAG;
typedef struct adjList_DAG *ptrToAdjList_DAG;//directed acyclic graph
typedef struct adjList_DAG *ptrToAdjList_uDAG;//undirected acyclic graph
typedef struct adjList_DAG *ptrToAdjList;//double, ud & d
typedef int** ptrToAdjMatrix_DAG;

typedef int* ptrToIndegreeArray;
typedef string Vertex;
typedef int Vertex_int;
typedef vector<Vertex_int> Vertex_vector;
typedef map<string, int> IndegreeMap;
typedef vector<string> TopSorted_name_vector;

struct distNode;
typedef struct distNode *DistNode;
typedef vector<DistNode> DistVector;

typedef DistVector tree_MST_Prim;
typedef pair<int, int> Edge;
typedef pair<Edge, int> Edge_info;
typedef vector<Edge_info> Edges;
typedef Edges tree_MST_Kruskal;


//1- createGraph
// uW-DAG(无权有向无圈图)|W-DAG(正权有向无圈图)|nW-DAG(负权有向无圈图)|W-uDAG(正权无向无圈图)
ptrToAdjList_DAG createGraph_adjList(int option, int v_num);
ptrToAdjMatrix_DAG createGraph_adjMatrix(int option, int v_num);
//2- getIndegree
// DG(有向图)
int* getIndegree_adjList(ptrToAdjList_DAG adj_list, int v_num);
int* getIndegree_adjMatrix(ptrToAdjMatrix_DAG adj_matrix, int v_num);
//3- findNewVertexOfIndegreeZero
Vertex findNewVertexOfIndegreeZero(IndegreeMap indegree_map);
//4- topolopy sort
// DAG(有向无圈图)
IndegreeMap transfer_array2map(ptrToIndegreeArray indegree_array, int v_num);
TopSorted_name_vector topSort(ptrToAdjList_DAG adj_list);
//5- findMinPath algorithms
//5.1 Unweighted Graph(uW-DAG)
void print_DistVector(DistVector dist_vector, int targetV);
DistVector createDistVector(ptrToAdjList_DAG adj_list, int targetV);
DistVector findMinPath_unweighted_1(ptrToAdjList_DAG adj_list, int targetV);
DistVector findMinPath_unweighted_2(ptrToAdjList_DAG adj_list, int targetV);
//5.2 Weighted Graph(Dijkstra)(W-DAG)
int getSmallestDist_unknowV(vector<int>& unknown_v, DistVector dist_vector);
DistVector findMinPath_weighted(ptrToAdjList_DAG adj_list, int targetV);
//5.3 Weighted Graph(negative)(nW-DAG)
bool isInq(int w_int, vector<int> q);
DistVector findMinPath_weighted_negative(ptrToAdjList_DAG adj_list, int targetV);
//6- minimum spanning tree(MST)
// W-uDAG(正权无向无圈图)
//(1)- Prim
tree_MST_Prim buildMST_Prim(ptrToAdjList_uDAG adj_list, int targetV);
//(2)- Kruskal
bool cmp(const Edge_info &e_info1, const Edge_info &e_info2);
void Edges_sort(Edges &edges);
//tree_MST_Kruskal buildMST_Kruskal(ptrToAdjList_uDAG adj_list);
//7- Graph Traversal
// (1)breadth-first search(BFS)
// (2)depth-first search(DFS)
Vertex_vector GraphTraversal_BFS(ptrToAdjList adj_list, int targetV);
void DFS(ptrToAdjList adj_list, int* nodeFlag_array, Vertex_vector &vertexs, int v_int);
Vertex_vector GraphTraversal_DFS(ptrToAdjList adj_list, int targetV);
  • SortFunctions:8大排序算法
// 冒泡排序,平均O(N ^ 2),最好O(N), 最差O(N ^ 2)
void bubbleSort(std::vector<int>& nums);
// 选择排序,平均O(N ^ 2),最好O(N ^ 2), 最差O(N ^ 2)
void selectionSort(std::vector<int>& nums);
// 插入排序,平均O(N ^ 2),最好O(N), 最差O(N ^ 2)
void insertSort(std::vector<int>& nums);
// 希尔排序,平均O((NlogN)^2),最好O(N), 最差O((NlogN)^2)
void shellSort(std::vector<int>& nums);
// 堆排序,平均O(NlogN),最好O(NlogN), 最差O(NlogN)
void heapSort(std::vector<int>& nums);
// 归并排序,平均O(NlogN),最好O(NlogN), 最差O(NlogN)
void mergeSortHelper(vector<int> &nums, int low, int high);
void merge(vector<int> &nums, int low, int mid, int high);
void mergeSort(std::vector<int>& nums);
// 快速排序,平均O(NlogN),最好O(NlogN), 最差O(N^2)
int paritition(vector<int>& nums, int low, int high);
void quickSortHelper(vector<int>& nums, int low, int high);
void quickSort(std::vector<int>& nums);
// 桶排序,平均O(N+K),最好O(N+K), 最差O(N^2)
void bucketSort(std::vector<int>& nums, int MAX);